package com.media.common.ffmpeg;

import com.media.common.Constants;
import org.assertj.core.util.Lists;
import org.bytedeco.javacpp.Loader;

import java.util.List;

/**
 * FFmpeg 工具类
 */
public class FFmpegUtil {

    /**
     * 获取到RTSP
     *
     * @param userName 用户名称
     * @param password 用户密码
     * @param ip       ip
     * @param channel  通道
     * @param stream   编码
     * @return 返回RTSP地址
     */
    public static String getRtsp(String userName, String password, String ip, String channel, String stream) {
        return Constants.RTSP +
                userName + ":" +
                password + "@" +
                ip +
                ":554/h264/ch" +
                channel + "/" +
                stream +
                "/av_stream";
    }


    /**
     * rtsp转视频
     */
    public static List<String> rtspToMp4(String rtsp, String realFile, String time) {
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-loglevel");
        commend.add("warning");
        commend.add("-rtsp_transport");
        commend.add("tcp");
        commend.add("-stimeout");
        commend.add("10000000");
        commend.add("-t");
        commend.add(time);
        commend.add("-i");
        commend.add(rtsp);
        commend.add("-c:v");
        commend.add("copy");
        commend.add("-f");
        commend.add("mp4");
        commend.add(realFile);
        return commend;
    }

    /**
     * 裁剪视频
     * <p>
     * -i input.mp4 指定输入视频文件。
     * -vcodec copy 和 -acodec copy 分别表示使用与原视频相同的视频和音频编解码器，以避免重新编码带来的质量损失和额外处理时间。
     * -ss 00:00:10 指定开始时间（格式为时:分:秒）。
     * -to 00:00:15 或 -t 00:00:05 分别指定结束时间或持续时间。
     * output.mp4 指定输出视频文件的名称。
     * -y 表示如果输出文件已存在，则覆盖它。
     */
    public static List<String> cutOutVideo(String mp4Path, String realFile, String start, String end) {
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-i");
        commend.add(mp4Path);
        commend.add("-vcodec");
        commend.add("copy");
        commend.add("-acodec");
        commend.add("copy");
        commend.add("-ss");
        commend.add(start);
        commend.add("-t");
        commend.add(end);
        commend.add(realFile);
        commend.add("-y");
        return commend;
    }


    /**
     * rtsp转图片 (一张)
     */
    public static List<String> rtspToImage(String rtsp, String tempFile) {

        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-y");
        commend.add("-loglevel");
        commend.add("warning");
        commend.add("-rtsp_transport");
        commend.add("tcp");
        commend.add("-stimeout");
        commend.add("1000000");
        commend.add("-t");
        commend.add("1");
        commend.add("-i");
        commend.add(rtsp);
        commend.add("-f");
        commend.add("image2");
        commend.add("-an");
        commend.add("-q:v");
        commend.add("-2");
        commend.add("-vf");
        commend.add("fps=fps=1");
        commend.add(tempFile);
        return commend;
    }

    /**
     * rtsp转图片 (持续 1秒一帧)
     */
    public static List<String> rtspContinueToImage(String rtsp, String imagePath, String time) {
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-y");
        commend.add("-loglevel");
        commend.add("warning");
        commend.add("-rtsp_transport");
        commend.add("tcp");
        commend.add("-stimeout");
        commend.add("1000000");
        commend.add("-i");
        commend.add(rtsp);
        commend.add("-vf");
//        commend.add("fps=1,scale=640:480"); //分辨率
        commend.add("fps=1");
        commend.add("-t");
        commend.add(time);
        commend.add("-q:v");
        commend.add("-2");
        commend.add(imagePath + "%d.jpg");
        return commend;
    }

    /**
     * rtsp 转 hls
     * ffmpeg
     * -i "rtsp://chgry:chgry888@192.168.16.219:554/h264/sub/av_stream"
     * -c copy
     * -f hls
     * -hls_time 3.0
     * -hls_list_size 2
     * -hls_wrap 1200
     * /home/wwwroot/ffmpeg/hls/test.m3u8
     * <p>
     * <p>
     * -hls_time n: 设置每片的长度，默认值为2。单位为秒
     * -hls_list_size n:设置播放列表保存的最多条目，设置为0会保存有所片信息，默认值为5
     * -hls_wrap n:设置多少片之后开始覆盖，如果设置为0则不会覆盖，默认值为0.这个选项能够避免在磁盘上存储过多的片，而且能够限制写入磁盘的最多的片的数量
     * -hls_start_number n:设置播放列表中sequence number的值为number，默认值为0
     */
    public static List<String> rtspToHls(String rtsp, String tempFile) {

        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-i");
        commend.add(rtsp);
        commend.add("-c");
        commend.add("copy");
        commend.add("-f");
        commend.add("hls");
        commend.add("-hls_time");
        commend.add("3.0");
        commend.add("-hls_list_size");
        commend.add("2");
        commend.add("-hls_wrap");
        commend.add("300");
        commend.add(tempFile);
        return commend;
    }

    /**
     * RTSP 转 RTMP
     * ffmpeg -i rtsp://your_rtsp_stream_address -c copy -f flv rtmp://your_rtmp_server_address/stream_key
     */
    public static List<String> rtspToRtmp(String rtsp, String rtmp) {

        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        List<String> commend = Lists.newArrayList();
        commend.add(ffmpeg);
        commend.add("-i");
        commend.add(rtsp);
        commend.add("-c");
        commend.add("copy");
        commend.add("-f");
        commend.add("flv");
        commend.add(rtmp);
        return commend;
    }

}
